/**
 * @description
 */


package com.yjx.crm;

import com.alibaba.fastjson.JSON;
import com.yjx.crm.base.ResultInfo;
import com.yjx.crm.exceptions.AuthException;
import com.yjx.crm.exceptions.NoLoginException;
import com.yjx.crm.exceptions.ParamsException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        /*
        * 非法请求拦截
        * */
        if (ex instanceof NoLoginException) {
            //重定向到登录页面
            ModelAndView mv = new ModelAndView("redirect:/index");
            return mv;
        }

      /*  方法返回值类型判断:
         如果方法级别存在@ResponseBody
         方法响应内容为json
         否则视图handler 参数类型为HandlerMethod返回值
         视图:默认错误页面
        json:错误的json信息*/
        ModelAndView modelAndView = new ModelAndView("error");
        //设置异常信息
        modelAndView.addObject("code",500);
        modelAndView.addObject("msg","异常异常，请重试...");

        //判断HandlerMethod
        if (handler instanceof HandlerMethod) {
            //类型转换
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            //获取方法上生命的@ResponseBody注解对象
            ResponseBody responseBody = handlerMethod.getMethod().getDeclaredAnnotation(ResponseBody.class);
            //判断ResponseBody对象是否为空
            if (responseBody == null) {
                /*
                * 方法返回视图
                */
                if (ex instanceof ParamsException) {
                    ParamsException p = (ParamsException) ex;
                    //设置异常信息
                    modelAndView.addObject("code",p.getCode());
                    modelAndView.addObject("msg",p.getMsg());
                } else if (ex instanceof AuthException) {
                    AuthException a = (AuthException) ex;
                    //设置异常信息
                    modelAndView.addObject("code",a.getCode());
                    modelAndView.addObject("msg",a.getMsg());
                }

                return modelAndView;
            } else {
                /*
                *方法返回数据
                **/
                ResultInfo resultInfo = new ResultInfo();
                resultInfo.setCode(500);
                resultInfo.setMsg("异常异常，请重试!");

                //判断异常类型是否为自定义异常
                if (ex instanceof ParamsException) {
                    ParamsException p = (ParamsException) ex;
                    resultInfo.setCode(p.getCode());
                    resultInfo.setMsg(p.getMsg());
                } else if (ex instanceof AuthException) {
                    AuthException a = (AuthException) ex;
                    resultInfo.setCode(a.getCode());
                    resultInfo.setMsg(a.getMsg());
                }
                //设置相应类型和编码格式
                response.setContentType("application/json;charset=UTF-8");
                //得到字符输出流
                PrintWriter out = null;
                try {
                    //得到输出流
                    out  = response.getWriter();
                    //将需要返回的对象转换成JSON格式的字符
                    String json = JSON.toJSONString(resultInfo);

                    //输出数据
                    out.write(json);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    //如果对象不为空，则关闭
                    if (out != null) {
                        out.close();
                    }
                }
                return null;
            }
        }

        return modelAndView;
    }
}
